#ifndef _SYMTABLE_
#define _SYMTABLE_

#include <iostream>
#include "Element.h"

#include "SymtableInterface.h"
#include "Hashtable.h"

using namespace std;

/**
* Die Symboltabelle verwaltet Char Array mit der Länge 20.0000. In diesen Char Arrays
* werden die Bezeichner für die Variablen hintereinander gespeichert. Ist kein freier Speicher mehr da, wird 1 neues 20.000er Array
* angelegt. Die Speicherreservierung steigt also linear und immer enorm, da selteneres Anlegen von großem Speicher
* performanter als öfteres anlegen von kleinem Speicher ist.
* 
* Die Zeiger, welche auf das erste Zeichen der Bezeichner zeigen,
* werden in einer Hashtabelle gespeichert, damit der Zugriff auf den Wert der Variablen schnell erfolgt und nicht lange
* nach den Zeigern gesucht werden muss. Die Kollisionsauflösung wird mit Hilfe von Listen realisiert.
* 
* Hashfunktion:
* 16 * (int) key[0] + 8 * (int) key[length - 1] + (int) length
*/
class Symtable : public SymtableInterface {
	/// Pointer, which points to an array of pointer for the string tabs
	char**	stringTabArray;
	/// Current count of string tabs - 1
	int		currentIndex;
	/// Free chars
	int		free;
	/// Length of a char array
	int		stringTabLength;
	/// Pointer for inserting. Points always at the end of the string tab array
	char*	insertPointer;
	/// Count of saved chars in the symtable
	int		charCount;
	/// Hashtable
	Hashtable<Element>* hashtable;
	/// Fügt einen weiteren string tab hinzu
	void addStringTabArray();
	/// Initialisiert symtable mit den reservierten Bezeichnern
	void initSymbols();

public:
	Symtable(int length);

	virtual ~Symtable();

	virtual Element* insert(char* lexem, int lexemLength, int tokenTyp);
	
	virtual Element* lookup(char* lexem, int lexemLength);

	virtual void printSymtable();

	virtual int getStringTabLength();

	virtual int getCurrentIndex();

	virtual char** getStringTabArray();

	virtual int getCharCount();
};

#endif // _SYMTABLE_
